#include "logsimpl.h"
#include "tablestruct.h"

CLogsImpl::CLogsImpl(void)
{

}
CLogsImpl::~CLogsImpl(void)
{
	logi("CLoginImpl::~CLoginImpl");
}
std_method_impl CLogsImpl::Init(int Argc, basic_tchar* Argv[], IBase* pRot, IBase* pBase)
{
	HRESULT hr = S_OK;
	rc_assert(pRot != NULL, E_FAIL)
	hr = pRot->QueryInterface(IID_IComRotMessage, (void**)&m_pRot);
	rc_assert(hr == S_OK, E_FAIL)

	hr = GetRuleFiles();
	rc_assert(hr == S_OK, E_FAIL)

	return S_OK;
}
std_method_impl CLogsImpl::Uninit()
{
	return S_OK;
}
std_method_impl CLogsImpl::Start(_pinstance hInstance, UINT uType)
{
	HRESULT hr = S_OK;
	hr = m_pRot->GetObject(CLSID_ILogDataBase, IID_ILogDataBase, (IBase**)&m_pILogDataBase);
	rc_assert(hr == S_OK, E_FAIL)
	rc_assert(m_pILogDataBase.m_p != INULL, E_FAIL)

	hr = m_pRot->GetObject(CLSID_ILogFilters, IID_ILogFilters, (IBase**)&m_pILogFilters);
	rc_assert(hr == S_OK, E_FAIL)
	rc_assert(m_pILogDataBase.m_p != INULL, E_FAIL)


	hr = LoadRuleFiles();

	return CreateTaskThread();
}
std_method_impl CLogsImpl::Stop(UINT uExitCode)
{
	HRESULT		hr = S_OK;

	CSemThread::Stop_Thread();

	return hr;
}

std_method_impl CLogsImpl::PostLog(UCHAR* pBuf, ULONG Size)
{
	HRESULT		hr = S_OK;

	rc_assert(pBuf != NULL, E_FAIL)
	rc_assert(Size != 0, E_FAIL)

	LogDataPtr ptr = new LogData(pBuf, Size);
	rc_assert(ptr != NULL, E_FAIL)

	LogDataPtr ptr1 = new LogData(pBuf, Size);
	rc_assert(ptr1 != NULL, E_FAIL)


	SYNC_OBJ(&m_lock);
	{
		m_ListJson.push_back(ptr);
		m_ListJson.push_back(ptr1);
	}
	return PostSem();
}
std_method_impl CLogsImpl::Sem_Thread_Run()
{
	HRESULT		hr = S_OK;


	TaskList listTemp;
	{
		SYNC_OBJ(&m_lock);
		listTemp.splice(listTemp.begin(), m_ListJson);
	}

	TaskListIterator it = listTemp.begin();
	for (; it != listTemp.end(); )
	{
		ProcessTask(*it);
		delete *it;
		++it;
	}

	return hr;
}

void get_file_cb_func(const basic_tchar* szPath, void* context)
{

	c_assert(szPath)
	c_assert(context)

	basic_tstring strPath(szPath);
	size_t index = strPath.find(_T(".xdt"));
	if (index == basic_tstring::npos) {

	}
	else {
		wdebug_view(szPath)
		wdebug_view(_T("\n"));
		CLogsImpl* p = static_cast<CLogsImpl*>(context);
		p->PushFile(strPath.c_str());
	}
}
std_method_impl CLogsImpl::GetRuleFiles()
{
	basic_tstring strPath = GetExePathString();
	GetFiles((basic_tchar*)strPath.c_str(), get_file_cb_func, this);
	return S_OK;
}

std_method_impl CLogsImpl::LoadRuleFiles()
{
	RuleListIterator it = m_RuleFiles.begin();
	while (it != m_RuleFiles.end())
	{
		ReadRuleFile(*it);
		++it;
	}
	return S_OK;
}
std_method_impl CLogsImpl::PushFile(const basic_tchar* file)
{
	m_RuleFiles.push_back(file);
	return S_OK;
}
std_method_impl CLogsImpl::CreateTaskThread()
{
	HRESULT		hr = S_OK;
	int rc = S_SUCCESS;

	rc = CSemThread::Start_Thread();
	rc_assert(rc == S_SUCCESS, S_ERROR)

	return hr;
}
std_method_impl CLogsImpl::UploadTask()
{
	HRESULT		hr = S_OK;

	return hr;
}
std_method_impl CLogsImpl::SendSemThread()
{
	HRESULT		hr = S_OK;

	return hr;
}
std_method_impl CLogsImpl::ProcessTask(LogDataPtr cmd)
{
	unsigned char* p = cmd->GetData();
	rc_assert(p != NULL, E_FAIL)

	unsigned long len = cmd->GetLen();
	rc_assert(len != 0, E_FAIL)

	m_pILogDataBase->InsertTable(p, len);

	return m_pILogFilters->PostLog(p, len);
}

std_method_impl CLogsImpl::ReadRuleFile(const basic_tstring& file)
{
	HRESULT		hr = S_OK;

	unsigned long ulen = 0;
	UCharArrayPtr pBuf = ReadFileMem(file, ulen);
	rc_assert(ulen > 0, E_FAIL);
	rc_assert(pBuf.m_p != NULL, E_FAIL);

	JsonSafePtr	pJsonRoot = cJSON_Parse((char*)pBuf.m_p);
	rc_assert(pJsonRoot.m_p != NULL, E_FAIL)
	rc_assert(IsJsonObject(pJsonRoot.m_p), E_FAIL);

	cJSON* pJsonLogs = cJSON_GetObjectItem(pJsonRoot, Rule_log);
	rc_assert(pJsonLogs != NULL, E_FAIL)
	rc_assert(IsJsonObject(pJsonLogs), E_FAIL);

	cJSON*pJsonTables = cJSON_GetObjectItem(pJsonLogs, Rule_Tables);
	rc_assert(pJsonTables != NULL, E_FAIL)
	rc_assert(IsJsonArray(pJsonTables), E_FAIL);

	int iloop = 0;
	for (iloop = 0; iloop < cJSON_GetArraySize(pJsonTables); iloop++)
	{
		cJSON* JsItem = cJSON_GetArrayItem(pJsonTables, iloop);

		if (IsJsonObject(JsItem))
		{
			SyncTable(JsItem);
		}
	}

	return hr;
}
std_method_impl CLogsImpl::SyncTable(const cJSON* JsRoot)
{
	rc_assert(JsRoot != NULL, E_FAIL);
	HRESULT		hr = S_OK;
	UINT		uFieldCount = 0;
	CTableStruct *pTable = new CTableStruct();
	rc_assert(pTable != NULL, E_FAIL)


	_lComPtr<ITableStruct> pITableStruct;
	hr = pTable->QueryInterface(IID_ITableStruct, (void**)&pITableStruct);
	rc_assert(hr == S_OK, E_FAIL)

	cJSON* pJsonTable = cJSON_GetObjectItem(JsRoot, Rule_Table);
	rc_assert(IsJsonString(pJsonTable), E_FAIL);

	pTable->SetTableName(pJsonTable->valuestring);
	//logi("SyncTable=>table_name=>%s", pJsonTable->valuestring);

	//hr = m_pILogDataBase->IsTableExist(pJsonTable->valuestring);
	//rc_assert_log(hr == S_OK, E_FAIL, "Fields_Table_Exist_Faild")

	cJSON* pJsonOp = cJSON_GetObjectItem(JsRoot, Rule_Op);
	rc_assert_log(IsJsonNumber(pJsonOp), E_FAIL, "Fields_Op_Faild")

	pTable->SetKeyValue(Rule_Op, pJsonOp->valueint);

	cJSON* pJsonSave = cJSON_GetObjectItem(JsRoot, Rule_Save);
	if (IsJsonNumber(pJsonTable))
	{
		pTable->SetKeyValue(Rule_Op, pJsonSave->valueint);
	}

	cJSON* pJsonFields = cJSON_GetObjectItem(JsRoot, Rule_Fields);
	rc_assert_log(IsJsonArray(pJsonFields), E_FAIL, "Fields_Array_Faild")

	int iloop = 0;

	FieldSturct field;
	for (iloop = 0; iloop < cJSON_GetArraySize(pJsonFields); iloop++)
	{
		cJSON* JsItem = cJSON_GetArrayItem(pJsonFields, iloop);
		if (IsJsonObject(JsItem))
		{
			s_memset(&field, 0, sizeof(FieldSturct));

			cJSON* pJsonFieldsName = cJSON_GetObjectItem(JsItem, Rule_Fields_Name);
			rc_assert_continue(IsJsonString(pJsonFieldsName));
			s_memcpy(&field.name, pJsonFieldsName->valuestring, FIELD_NAME_LEN);

			cJSON* pJsonFieldsType = cJSON_GetObjectItem(JsItem, Rule_Fields_Type);
			rc_assert_continue(IsJsonString(pJsonFieldsType));
			s_memcpy(&field.type, pJsonFieldsType->valuestring, FIELD_TYPE_LEN);

			cJSON* pJsonFieldsSize = cJSON_GetObjectItem(JsItem, Rule_Fields_Size);
			if (IsJsonNumber(pJsonFieldsSize)) {
				field.size = pJsonFieldsSize->valueint;
			}
			cJSON* pJsonFieldsIndex = cJSON_GetObjectItem(JsItem, Rule_Fields_Index);
			if (IsJsonNumber(pJsonFieldsIndex)) {
				field.index = pJsonFieldsIndex->valueint;
			}

			//insert faild ????
			pTable->SetRecord(field);
		}
	}

	pTable->GetFieldsCount(uFieldCount);
	rc_assert_log(uFieldCount > 0, E_FAIL, "Table_Field_Count_Faild")

	hr = m_pILogDataBase->SyncTable(pJsonTable->valuestring, pTable);
	rc_assert_log(hr == S_OK, E_FAIL, "Table_Sync_Faild")


	return S_OK;
}

